#include <iostream>
#include <cmath>
using namespace std;
template <typename F, typename T, unsigned N>
class nth_derivative{
using prev_derivative=nth_derivative<F, T, N-1>;
public:
nth_derivative(const F& f, const T& h): h(h), fp(f, h) {}
T operator()(const T& x) const{
return N&1?(fp(x+h)-fp(x))/h:(fp(x)-fp(x-h))/h;
}
private:
T h;
prev_derivative fp;
};
template <typename F, typename T>
class nth_derivative<F, T, 1>{
public:
nth_derivative(const F& f, const T& h): f(f), h(h) {}
T operator()(const T& x) const{
return (f(x+h)-f(x))/h;
}
private:
const F& f;
T h;
};
class psc_f{
public:
psc_f(double alpha): alpha(alpha) {}
double operator()(double x) const{
return sin(alpha*(x))+cos(x);
}
private:
double alpha;
};
int main(void){
nth_derivative<psc_f, double, 22> d22_psc_o(psc_f(1.0), 0.00001);
cout<<"22nd der. of sin(0)+cos(0) is "<<d22_psc_o(0.0)<<'\n';
return 0;
}